package com.edu.juc.completableFuture.example;

import com.edu.juc.completableFuture.example.bean.NetMall;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;

public class CompletableFutureMallTest2 {
    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        List<NetMall> list = Arrays.asList(
                new NetMall("jd"),
                new NetMall("taobao"),
                new NetMall("tmall"),
                new NetMall("amazon")
        );

        List<BigDecimal> prices =
                // 1. 异步任务并行启动
                // 对 list 中的每个 netMall 对象，supplyAsync 会立即提交一个异步任务到线程池（默认使用 ForkJoinPool）。
                // 这些任务会并行执行 getPrice("book") 方法，而非顺序执行。
                // 非阻塞提交：
                // 第一段 Stream 操作仅创建 CompletableFuture 对象列表，不等待任务完成。
                // 此时所有价格查询任务已在后台线程中并发运行
                list.stream().map(netMall -> CompletableFuture.supplyAsync(() ->
                                netMall.getPrice("book")
                        ))
                        .toList()
                        // 2. 阻塞等待与结果聚合
                        // 第二段 Stream 对每个 CompletableFuture 调用 join()。该方法会阻塞当前线程直到任务完成**，但关键点在于：
                        // 所有任务已提前启动：因任务在第一阶段已并行执行，此时 join() 只需按顺序等待结果返回。
                        // 即使某些任务耗时较长，其他任务仍可在后台并行执行
                        // 结果按顺序收集：join() 返回结果时，map 操作将结果按原列表顺序聚合到新的 List<BigDecimal> 中
                        .stream()
                        .map(task->{
                            BigDecimal result = task.join();
                            System.out.println("任务完成：" + result);
                            return result;
                        })
                        .toList();
        long endTime = System.currentTimeMillis();
        System.out.println("总耗时：" + (endTime - startTime));
        prices.forEach(System.out::println);
    }
}
